
package com.hulk.ratel.common.security;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.crypto.asymmetric.SignAlgorithm;
import cn.hutool.crypto.symmetric.AES;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.StandardCharsets;
import java.security.*;

/**
 * @author hulk
 * @version Create on:  2017年4月28日 上午11:32:07
 *          Class description
 * @E-mail:29572320@qq.com
 */

@Slf4j
@UtilityClass
public class ProvideSecurityWarper {

    /**
     * 用platformPriKey解密encryptKey
     *
     * @param cipherB64PartnerAESkey
     * @param platformPrivateKey
     * @return
     */
    public  String getPartnerAESKeyByPlatformPrivateKey(String cipherB64PartnerAESkey, PrivateKey platformPrivateKey) {

        RSA rsa = new RSA();
        rsa.setPrivateKey(platformPrivateKey);
        return   StrUtil.str(rsa.decrypt(Base64.decode(cipherB64PartnerAESkey, StandardCharsets.UTF_8), KeyType.PrivateKey),StandardCharsets.UTF_8);


    }


    /**
     * 用partnerAESKey解密encryptData
     *
     * @param cipherB64PlainText
     * @param partnerAESKey
     * @return
     */
    public  String getPlainTextByAESKey(String cipherB64PlainText, String partnerAESKey) {

        AES aes = new AES(Mode.ECB, Padding.PKCS5Padding,partnerAESKey.getBytes(StandardCharsets.UTF_8));
        //解密
        String plainText = StrUtil.str(aes.decrypt(Base64.decode(cipherB64PlainText, StandardCharsets.UTF_8)),StandardCharsets.UTF_8);
        return plainText;

    }

    /**
     * 用partnerPubKey验证签名
     *
     * @param plainText
     * @param mac
     * @param partnerPublicKey
     * @return
     */
    public  boolean checkSignB64PlainTextByPartnerPublicKey(String plainText, String mac, PublicKey partnerPublicKey) {



        boolean isValid ;
        try {
            byte [] plainBytes = plainText.getBytes(StandardCharsets.UTF_8);
            byte[] signPlainBytes = Base64.decode(mac);
            Signature signature = Signature.getInstance(SignAlgorithm.SHA256withRSA.getValue());
            signature.initVerify(partnerPublicKey);
            signature.update(plainBytes);
            isValid = signature.verify(signPlainBytes);
            return isValid;
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(String.format("验证数字签名时没有[%s]此类算法", SignAlgorithm.SHA256withRSA.getValue()),e);
        } catch (InvalidKeyException e) {
            throw new RuntimeException("验证数字签名时公钥无效",e);
        } catch (SignatureException e) {
            throw new RuntimeException("验证数字签名时出现异常",e);
        }

    }


}
